﻿function ECommerceProductsViewModel(context) {

    var self = this;

    var spinner = new SpinnerModel();

    var mode = ko.observable('all');

    var currentRoute = ko.computed(function () {
        var m = mode();
        switch (m) {
            case 'all':
                return context.spaRuntime.findRouteByName('products');
            case 'search':
                return context.spaRuntime.findRouteByName('productsSearch');
            case 'tag':
                return context.spaRuntime.findRouteByName('productsByTag');
            default:
                return null;
        }
    });

    var pager = new PagerCountModel(function (page) {
        return getPageUrl(page, pageSize());
    });

    var pageNumber = pager.pageNumber;
    var pageSize = pager.pageSize;
    var totalCount = pager.itemsCount;

    var products = context.products;

    var productInfoRoute = context.spaRuntime.findRouteByName('product');
    var productsByTag = context.spaRuntime.findRouteByName('productsByTag');

    var tagCriteria = '';
    pageSize(10);

    function setProducts(raw) {
        if (raw) {
            pager.itemsCount(raw.totalCount);
            var items = raw.products;
            var res = [];
            for (var i = 0; i < items.length; i++) {
                var info = items[i];
                var item = new ProductModel(info);
                res.push(item);
            }
            if (pager.pageNumber() > pager.pagesCount()) {
                window.location.hash = pager.getLinkTo(pager.pagesCount());
            }
            products(res);
        } else {
            products([]);
        }
    }

    function reload() {
        switch (mode()) {
            case 'all':
                reloadAll();
                break;
            case 'search':
                reloadSearch(context.searchTerm());
                break;
            case 'tag':
                reloadTag(tagCriteria);
                break;
        }
    }

    function reloadAll() {
        var api = context.api();

        spinner.enter();

        //We grab the first tag and load products for that when reloading everything
        api.products.getTags(function (data) {
            spinner.leave();
            if(data !== null && data.length > 0)
                reloadTag(data[0]);
        });
    }

    function reloadSearch(term) {
        var api = context.api();
        var page = pageNumber();
        var ps = pageSize();
        api.products.searchProductsPage(term, page, ps, function (data) {
            spinner.leave();
            setProducts(data);
        }, function () {
            spinner.leave();
            setProducts(null);
        });
    }

    function reloadTag(tag) {
        var api = context.api();
        var page = pageNumber();
        var ps = pageSize();
        spinner.enter();
        api.products.listForTag(tag, page, ps, function (data) {
            spinner.leave();
            setProducts(data);
        }, function () {
            spinner.leave();
            setProducts(null);
        });
    }

    function processArgs(args) {
        if (args) {
            if (args.pageNumber) pageNumber(parseInt(args.pageNumber));
            else pageNumber(1);
            if (args.pageSize) pageSize(parseInt(args.pageSize));
        }
    }

    function showAll(args) {
        processArgs(args);
        mode('all');
        reloadAll();
    }

    function search(term, args) {
        processArgs(args);
        if (!term) {
            showAll();
        } else {
            mode('search');
            reloadSearch(term);
        }
    }

    function searchTag(tag, args) {
        processArgs(args);
        if (!tag) {
            showAll();
        } else {
            mode('tag');
            tagCriteria = tag;
            reloadTag(tag);
        }
    }

    function addToCart(product) {
        context.addToCart(product);
    }

    function getProductUrl(product) {
        return productInfoRoute.formatHash({
            id: product.id()
        });
    }

    function getByTagUrl(tag) {
        return productsByTag.formatHash({
            tag: tag
        });
    }

    function getPageUrl(pn, ps) {
        var spaRuntime = context.spaRuntime;
        var route = currentRoute();
        var arg = spaRuntime.getCurrentArgs();
        arg = $.extend({}, arg, {
            pageNumber: pn,
            pageSize: ps
        });
        return route.formatHash(arg);
    }

    pageSize.subscribe(function () {
        var url = getPageUrl(pageNumber(), pageSize());
        window.location.hash = url;
    });

    self.spinner = spinner;
    self.showAll = showAll;
    self.search = search;
    self.searchTag = searchTag;
    self.reload = reload;
    self.products = products;
    self.addToCart = addToCart;
    self.getProductUrl = getProductUrl;
    self.getByTagUrl = getByTagUrl;
    self.pager = pager;
    self.pageSize = pageSize;
    self.totalCount = totalCount;
}